#include "RenderContext.h"

#include <osg/DisplaySettings>
#include <osgEarth/MapNode>
#include <osgEarthUtil/EarthManipulator>

osgViewer::View* CRenderContext::GetView()
{
	return m_rpViewer.get();
}

osg::Group* CRenderContext::GetRoot()
{
	return m_rpRoot.get();
}

osgEarth::MapNode* CRenderContext::GetMapNode()
{
	return m_rpMapNode.get();
}

bool CRenderContext::Initialize(std::string strDataPath /*= ""*/)
{
	m_rpViewer = new osgViewer::Viewer();
	m_rpCompositeViewer = new osgViewer::CompositeViewer();
	m_rpCompositeViewer->addView(m_rpViewer);

	osgEarth::Util::EarthManipulator* manip = new osgEarth::Util::EarthManipulator();
	m_rpViewer->setCameraManipulator( manip );

	/*m_rpViewer->getCamera()->setNearFarRatio(0.0000003);
	m_rpViewer->getCamera()->setClearMask(m_rpViewer->getCamera()->getClearMask() | GL_STENCIL_BUFFER_BIT);
	m_rpViewer->getCamera()->setClearStencil(0);
	m_rpViewer->getCamera()->setSmallFeatureCullingPixelSize(-1.0f);*/
	//m_rpViewer->setUpViewOnSingleScreen(0);

	m_rpCompositeViewer->setThreadingModel(osgViewer::ViewerBase::SingleThreaded);

	osg::DisplaySettings* ds = osg::DisplaySettings::instance();
	ds->setNumMultiSamples(4);
	m_rpViewer->setDisplaySettings(ds);

	m_rpMapNode = osgEarth::MapNode::findMapNode(osgDB::readNodeFile("f:/FreeEarth_flat.earth"));

	if (!m_rpMapNode.valid())
	{
		return false;
	}

	m_rpViewer->getDatabasePager()->setDoPreCompile(true);
	m_rpViewer->getDatabasePager()->setUpThreads(2);

	m_rpRoot = new osg::Group;
	m_rpViewer->setSceneData(m_rpRoot.get());

	m_rpRoot->addChild(m_rpMapNode.get());

	return true;
}

bool CRenderContext::Uninitialize()
{
	if (m_rpCompositeViewer.valid())
	{
		m_rpCompositeViewer->setDone(true);
		m_rpCompositeViewer->removeView(m_rpViewer.get());
	}

	return true;
}

void CRenderContext::Frame()
{
	if ((m_rpCompositeViewer->getRunFrameScheme() == osgViewer::ViewerBase::CONTINUOUS || m_rpCompositeViewer->checkNeedToDoFrame())
		&& !m_rpCompositeViewer->done())
	{
		m_rpCompositeViewer->frame();
	}
}

osg::GraphicsContext::Traits* CRenderContext::CreateTraits(osg::Referenced* pInheritedWindowData, int nX, int nY, int nW, int nH)
{
	osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits();
	traits->readDISPLAY();
	if (traits->displayNum<0) traits->displayNum = 0;

	traits->windowName = "FreeEarth";
	traits->windowDecoration = false;
	traits->x = nX;
	traits->y = nY;
	traits->width = nW;
	traits->height = nH;
	traits->doubleBuffer = true;
	traits->inheritedWindowData = pInheritedWindowData;

	return traits.release();
}

bool CRenderContext::SetGraphicContext(osg::GraphicsContext* pContext)
{
	if (!pContext || !m_rpViewer.valid())
	{
		return false;
	}

	osg::Camera* pCamera = m_rpViewer->getCamera();
	if (pCamera->getGraphicsContext() != pContext)
	{
		pCamera->setGraphicsContext(pContext);
		if (!pCamera->getViewport())
		{
			pCamera->setViewport(new osg::Viewport(0, 0, pContext->getTraits()->width, pContext->getTraits()->height));
		}

		pCamera->setProjectionMatrixAsPerspective(30.0f, pCamera->getViewport()->width() / pCamera->getViewport()->height(), 1.0f, 10000.0f);
	}

	return true;
}

